package com.zijie.hosptal.aop;

import com.zijie.hosptal.util.ThreadLocalUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
public class AutoFillAspect {
    //切点
    @Pointcut("execution(* com.zijie.hosptal.service.impl.*.*(..)) && @annotation(com.zijie.hosptal.aop.AutoFill)")
    public void autoFillPointCut(){
    }
    //通知
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        MethodSignature signature=(MethodSignature)joinPoint.getSignature();
        // 获得加载方法上面的注解 AutoFill的值
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        OperationType value = autoFill.value();
        //被拦截的参数
        Object[] args = joinPoint.getArgs();
        if(args==null||args.length==0){
            return;
        }
        //基本上就是实体类 ----->隐含实体类要放在参数列表的第一位
        Object arg = args[0];
        //当前时间
        LocalDateTime now = LocalDateTime.now();
        String username= ThreadLocalUtil.get("name");
        if(value== OperationType.INSERT){
            try {
                //填充创建时间、更新时间、创建人、更新人
                Method setCreateTime = arg.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                setCreateTime.invoke(arg, now);
                Method setUpdateTime = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                setUpdateTime.invoke(arg, now);
                Method setCreateUser = arg.getClass().getDeclaredMethod("setCreateUser", String.class);
                setCreateUser.invoke(arg, username);
                Method setUpdateUser = arg.getClass().getDeclaredMethod("setUpdateUser", String.class);
                setUpdateUser.invoke(arg, username);
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        } else if (value == OperationType.UPDATE) {
            try {
                //填充更新时间、更新人
                Method setUpdateTime = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                setUpdateTime.invoke(arg, now);
                Method setUpdateUser = arg.getClass().getDeclaredMethod("setUpdateUser", String.class);
                setUpdateUser.invoke(arg, username);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
